package com.dubbo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dubbo.common.ResponseUtil;
import com.dubbo.common.check.CheckUtil;
import com.dubbo.common.file.FileUtil;
import com.dubbo.common.id.SnowflakeIdUtil;
import com.dubbo.common.push.JpushClientUtil;
import com.dubbo.common.pwd.Md5Utils;
import com.dubbo.common.redis.RedisDao;
import com.dubbo.common.redis.tool.RedisConstant;
import com.dubbo.common.result.ResultInfo;
import com.dubbo.common.security.SecurityUtils;
import com.dubbo.common.security.bean.UserBean;
import com.dubbo.domain.User;
import com.dubbo.domain.UserWalletKey;
import com.dubbo.domain.Wallet;
import com.dubbo.domain.auth.RoleUserKey;
import com.dubbo.domain.dto.UserDto;
import com.dubbo.domain.info.ResultMessage;
import com.dubbo.domain.other.UserInfo;
import com.dubbo.mapper.UserMapper;
import com.dubbo.mapper.UserWalletKeyMapper;
import com.dubbo.mapper.WalletMapper;
import com.dubbo.mapper.auth.PermissionMapper;
import com.dubbo.mapper.auth.RoleMapper;
import com.dubbo.mapper.auth.RoleUserKeyMapper;
import com.dubbo.service.business.user.UserService;
import com.dubbo.service.impl.base.BaseServiceImpl;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;


/**
 * 
 * 用户信息
 * @author zhangxiaofei
 * 2018年7月28日 下午3:15:21
 */
@Service
@Transactional(readOnly = false,rollbackFor=Exception.class)
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService {

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private WalletMapper walletMapper;
	@Autowired
	private UserWalletKeyMapper walletKeyMapper;
	@Autowired
	private RedisDao redisDao;
	@Autowired
	private PermissionMapper permissionMaper;
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private RoleUserKeyMapper roleUserKeyMapper;
	@Value("${user.prefixkey.redis}")
	private String userTicket;
	@Value("${shiro.session.timeout}")
	private long userSeconds;
	@Value("${plainId}")
	private String plainId;
	private static final String FILE_SUFFIX = "png";
	/**
	 * 
	 * 根据微信用户参数创建会员用户
	 */
	@Override
	public Map<String, Object> registerUserByWechat(UserDto userDto, HttpServletRequest request,
													HttpServletResponse response) {
		// 校验微信数据
		// 微信用户参数
		UserInfo userInfo = userDto.getUserInfo();
		// 只对当前公众号唯一的表示
		String openId = userDto.getOpenId();
		// 根据微信数据注册会员
		String nickName = userInfo.getNickName();
		// 通过openid查询用户数据
		User user = new User();
		user.setOpenId(openId);
		List<User> userList = userMapper.select(user);
		
		if (userList != null && !userList.isEmpty()) {
			user = userList.get(0);
			if(user.getUserstatus()!=1) {
				return ResponseUtil.ajaxCheckError(ResultMessage.USER_FROZEN);
			}
			user.setWxName(nickName);
			userMapper.updateByPrimaryKeySelective(user);
			String key = this.saveUserByRedis(redisDao, user);
			return ResponseUtil.ajaxCheckSuccess("登录成功!", ResultInfo.USERTOKEN, key);
		}
		
		
		// 微信的性别 1=男性，2=女性，0=未知
		//String gender = userInfo.getGender();
		// 微信头像
		//String avatarUrl = userInfo.getAvatarUrl();
		// 微信语言
		/*String language = userInfo.getLanguage();
		// 微信所属国家
		String country = userInfo.getCountry();
		// 微信所在省份
		String province = userInfo.getProvince();
		// 微信所在城市
		String city = userInfo.getCity();*/
		
		user=new User();
		user.setId(UUID.randomUUID().toString().replace("-", ""));
		//user.setWxId(getData());
		// 设置创建时间
		user.setCreateTime(new Date());
		user.setUpdateTime(new Date());
		user.setWxName(nickName);
		user.setOpenId(openId);
		user.setUserstatus(1); //正常用户
		//user.setAvatarurl(avatarUrl);
		/*user.setLanguage(language);
		user.setCountry(country);
		user.setProvince(province);
		user.setCity(city);*/
		
		// 如果gender=2 返回0(女) gender=1或0 返回1(男)
		//gender = gender.equals("2") ? "0" : "1";
		//user.setSex(new Integer(gender));
		//user.setUserstatus(1);
		//user.setLevel(0);
		
		// 如果是微信用户授权的会员是没有账号和密码的
		userMapper.insertSelective(user);
		
		/*//生成相关的钱包
		Wallet wallet = new Wallet();
		wallet.setId(UUID.randomUUID().toString().replace("-", ""));
		wallet.setCreateTime(new Date());
		wallet.setUpdateTime(new Date());
		walletMapper.insertSelective(wallet);
		
		// 生成相关的钱包关系
		UserWalletKey walletKey=new UserWalletKey();
		walletKey.setUserid(user.getId());
		walletKey.setWalletid(wallet.getId());
		walletKeyMapper.insertSelective(walletKey);*/
		
		// 将用户数据保存到redis中并将redis中的key返回
		String key = this.saveUserByRedis(redisDao, user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.LOGIN_SUCCESS, ResultInfo.USERTOKEN, key);
	}
	
	/**
	 * 将用户数据保存到redis中并将redis中的key返回
	 */
	@Override
	public String saveUserByRedis(RedisDao redisDao, User user) {
		String ownerJson = JSON.toJSONString(user);
		String uuidKey = UUID.randomUUID().toString();
		String key = RedisConstant.getKey(userTicket, uuidKey);
		redisDao.set(key, ownerJson, userSeconds);
		return key;
	}

	/**
	 * 
	 * 个人信息
	 */
	@Override
	public Map<String, Object> personalInformation(String userId) {
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK, userMapper.selectByPrimaryKey(userId));
	}

	/**
	 * 
	 * 修改或者绑定手机号
	 * 修改时加多一个password字段
	 */
	@Override
	public Map<String, Object> changePhone(HttpServletRequest request, User user, String phone, String code,String password) {

		if (!StringUtils.isNoneBlank(phone)) {
			return ResponseUtil.ajaxCheckError(ResultInfo.SYSTEM_ERROR, "phone");
		}

		// 判断手机账号是否合法
		if (!CheckUtil.checkMobile(phone)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_ERROR, "phone");
		}
		User userByPhone = userMapper.getUserByPhone(phone);
		if(userByPhone!=null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_BE_REGIST, "phone");
		}
		if (!StringUtils.isNoneBlank(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR, "code");
		}
		if(!StringUtils.isNumeric(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR);
		}
		// 判断密码是否为空
		if (StringUtils.isNotBlank(password)) {
			// 密码MD5加密(盐为手机号;)
			String md5Pws = Md5Utils.MD5AddSalt2(password, user.getPhone());
			if (user== null||!user.getPassword().equals(md5Pws)) {
				return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR, "phone or password is error~");
			}
		}
		// 校验验证码
		Map<String, Object> checkCode = CheckUtil.checkCode(phone, code, redisDao);
		if (checkCode != null) {
			return checkCode;
		}
		
		user.setPhone(phone);
		String md5Pws = Md5Utils.MD5AddSalt2(password,phone);
		user.setPassword(md5Pws);
		user.setUpdateTime(new Date());
		
		userMapper.updateByPrimaryKeySelective(user);

		// 更新reids和cookie中的用户数据
		String key = saveUserByRedis(redisDao, user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.UPDATE_SUCCESS, ResultInfo.USERTOKEN, key);
	}

	/**
	 * 
	 * 修改性别
	 * 
	 */
	@Override
	public Map<String, Object> changeSex(User user, Integer sex) {
		
		if(sex==null) {
			return ResponseUtil.ajaxCheckError(ResultInfo.SYSTEM_ERROR, "sex");
		}
		if(sex<0&&sex>1) {
			return ResponseUtil.ajaxCheckError(ResultInfo.SYSTEM_ERROR, "sex");
		}
		
		user.setSex(sex);
		user.setUpdateTime(new Date());
		
		userMapper.updateByPrimaryKeySelective(user);
		
		//将用户数据保存到redis中并将redis中的key返回
		String key = saveUserByRedis(redisDao, user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.UPDATE_SUCCESS,ResultInfo.USERTOKEN,key);	
	}

	/**
	 * 
	 * 修改爱好
	 * 
	 */
	@Override
	public Map<String, Object> changeHobby(User user, String hobbyJson) {
		if(StringUtils.isNoneBlank(hobbyJson)) {
			List<String> list = JSONObject.parseArray(hobbyJson,String.class);
			StringBuilder str=new StringBuilder();
			for(int i=0;i<list.size();i++)
			{
				if(i==list.size()-1){
					str.append(list.get(i));
				}else{
					str.append(list.get(i));
					str.append(",");
				}
			}
			user.setHobby(str.toString());
			user.setUpdateTime(new Date());
			
			userMapper.updateByPrimaryKeySelective(user);
			// 更新reids和cookie中的用户数据
			String key = saveUserByRedis(redisDao, user);
			return ResponseUtil.ajaxCheckSuccess(ResultMessage.UPDATE_SUCCESS, ResultInfo.USERTOKEN, key);
		}else {
			user.setHobby(null);
			user.setUpdateTime(new Date());
			
			userMapper.updateByPrimaryKeySelective(user);
			// 更新reids和cookie中的用户数据
			String key = saveUserByRedis(redisDao, user);
			return ResponseUtil.ajaxCheckSuccess(ResultMessage.UPDATE_SUCCESS, ResultInfo.USERTOKEN, key);
		}
	}

	/**
	 * 根据用户id获取昵称,微信id,头像路径,钱包余额,红包余额
	 */
	@Override
	public Map<String, Object> getUserInformation(String userId) {
		if(!StringUtils.isEmpty(userId)){
			return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK, userMapper.getUserInformation(userId));
		}else{
			return ResponseUtil.ajaxCheckError(ResultMessage.PARAMETER_NULL);
		}
	}
	
	/**
	 * 
	 * 随机生成0-9的10位数ID
	 *
	 * @author zhangxiaofei
	 * 2018年8月6日 上午10:36:59
	 * @return
	 */
	/*private String getData() {
		List<String> list = new ArrayList<String>(); // 存放数据 
		Random r = new Random(); 
		String str = ""; 
		for (int i = 0; i < 10; i++) { // 循环10次 
			Integer x = r.nextInt(10); // 0-9的随机数 
			str += x.toString(); // 拼成10位数 因为int类型只能存放200000000+的数据，所以只能用字符串拼接 
		} 
		if(list.contains(str)) { //存在则再生成一次数据 
			this.getData(); 
		} 
		return str; 
	}*/

	/**修改地址
	 * @param addressJson
	 * @return
	 * @author lihongwu
	 * @date 2018年8月21日下午5:19:45
	 */
	@Override
	public Map<String, Object> changeAddress(User user,String addressJson) {
		JSONArray jsonArray = JSON.parseArray(addressJson);
		String province = jsonArray.getString(0);
		String city = jsonArray.getString(1);
		String area = jsonArray.getString(2);
		user.setProvince(province);
		user.setCity(city);
		user.setCountry(area);
		userMapper.updateByPrimaryKeySelective(user);
		// 更新reids和cookie中的用户数据
		String key = saveUserByRedis(redisDao, user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.UPDATE_SUCCESS, ResultInfo.USERTOKEN, key);
		
	}
	
	/**
	 * 注册账号
	 *
	 * @author lihongwu
	 * 2018年11月9日 下午6:08:13
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 * @throws IOException 
	 */
	@Override
	public Map<String, Object> registUser(HttpServletRequest request,String name,String phone, String code, String password,
			String repassword,String province,String city,String area,String shopName,String path) throws IOException {
		if(StringUtils.isBlank(name)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.NAME_IS_NULL);
		}
		if(StringUtils.isBlank(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_IS_NULL);
		}
		if(!CheckUtil.checkChineseStr(name, 8)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.NAME_STRING_ERROR);
		}
		if(StringUtils.isNoneBlank(shopName) && !CheckUtil.checkChineseStr(shopName, 10)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.SHOPNAME_STRING_ERROR);
		}
		if(!CheckUtil.checkMobile(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_ERROR);
		}
		if(userMapper.checkPhoneExist(phone)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_BE_REGIST);
		}
		if (!StringUtils.isNoneBlank(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR, "code");
		}
		if(!StringUtils.isNumeric(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR);
		}
		//校验验证码
		/*Map<String, Object> checkCode = CheckUtil.checkCode(phone, code, redisDao);
		if(checkCode!=null){
			return checkCode;
		}*/
		if(password!=null && (password.length()<7 || password.length()>16)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PASSWORD_IS_EROOR);
		}
		if(!CheckUtil.checkPwd(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PASSWORD_ERROR);
		}
		if(!repassword.equals(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.REPASSWORD_ERROR);
		}
		
		// 设置用户编号(雪花)
		Calendar now = Calendar.getInstance();
		String orderNum = SnowflakeIdUtil.nextId(3699L, System.currentTimeMillis()) + "";
		String nowTime = (Integer.parseInt(String.valueOf(now.get(Calendar.YEAR)).substring(2)) + "")
				+ (String.format("%02d", (now.get(Calendar.MONTH) + 1)))
				+ (String.format("%02d", now.get(Calendar.DAY_OF_MONTH)))
				+ (String.format("%02d", now.get(Calendar.HOUR_OF_DAY)))
				+ (String.format("%02d", now.get(Calendar.MINUTE)));
		String startLetter = "USER";
		
		String passwordMd5 = Md5Utils.getPassword(password,phone);
		User user = new User();
		user.setId(UUID.randomUUID().toString().replace("-", ""));
		user.setPhone(phone);
		user.setNickName(name);
		user.setPassword(passwordMd5);
		user.setUsernum(startLetter + nowTime + orderNum);
		user.setCountry(province);  //国这个字段当省用
		user.setProvince(city);     //省当城市用
		user.setCity(area);    //城市当区用
		if(StringUtils.isNoneBlank(shopName)) {
			user.setShopname(shopName);
		}
		user.setUserstatus(1);
		user.setLevel(0);
		user.setType(0);
		user.setCreateTime(new Date());
		user.setUpdateTime(new Date());
		userMapper.insertSelective(user);
		
		//制作二维码
		String localPath = request.getSession().getServletContext().getRealPath("/")+"image/";
		String qrCodePath = this.getQRCode(path, localPath,"userId"+user.getId(), 300, 300);
		user.setCodea(qrCodePath);
		user.setUpdateTime(new Date());
		userMapper.updateByPrimaryKeySelective(user);
		
		//将用户与普通用户角色关联
		RoleUserKey roleUserKey = new RoleUserKey();
		roleUserKey.setUserid(user.getId());
		roleUserKey.setRoleid(plainId);
		roleUserKeyMapper.insert(roleUserKey);
		
		//生成相关的钱包
		Wallet wallet = new Wallet();
		wallet.setId(UUID.randomUUID().toString().replace("-", ""));
		wallet.setMoney("0");
		wallet.setOutmoney("0");
		wallet.setHistorymoney("0");
		wallet.setCreateTime(new Date());
		wallet.setUpdateTime(new Date());
		walletMapper.insertSelective(wallet);
		
		// 生成相关的钱包关系
		UserWalletKey walletKey=new UserWalletKey();
		walletKey.setUserid(user.getId());
		walletKey.setWalletid(wallet.getId());
		walletKeyMapper.insertSelective(walletKey);
		
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK);
	}
	
	/**
	 * 登录
	 *
	 * @author lihongwu
	 * 2018年11月9日 下午6:08:05
	 * @param phone
	 * @param password
	 * @return
	 * @throws Exception 
	 */
	@Override
	public Map<String, Object> login(String phone, String password,String registrationId) throws Exception {
		// 判断手机号密码是否为空
		if(StringUtils.isBlank(phone)||StringUtils.isBlank(password)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR, "phone or password is null");
		}
		
		//密码MD5加密(盐为手机号;)
		String md5Pws = Md5Utils.MD5AddSalt2(password,phone);
		//判断是否存在
		User user = userMapper.selectByPhoneAndPwd(phone,md5Pws);
		if(user==null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR, "user is null");
		}
		
		user = userMapper.selectByPrimaryKey(user.getId());
		//单方登录
		if(user!=null&&user.getRegistrationId()!=null&&StringUtils.isNotBlank(user.getRegistrationId())
				&&registrationId!=null&&StringUtils.isNotBlank(registrationId)&&!user.getRegistrationId().equals(registrationId)) {
			JpushClientUtil.initJPushClient(ResultMessage.JGTSKEY, ResultMessage.JGTSECRET);
			Map<String,String> map = new HashMap<>();
			map.put("code", "000000");
			map.put("msg", "您的账号已在其它地方登陆，若不是本人操作，请注意账号安全！");
			JpushClientUtil.sendToRegistrationId(user.getRegistrationId(),"","","", "", "", "",map);
		}
		if(registrationId!=null&&StringUtils.isNotBlank(registrationId)) {
			user.setRegistrationId(registrationId);  //设置设备id
		}
		userMapper.updateByPrimaryKeySelective(user);
		UserBean userBean = new UserBean();
		List<String> list = permissionMaper.getPermissionsByUserId(user.getId());
		userBean.setPermissions(list);
		List<String> list2 = roleMapper.getRolesByUserId(user.getId());
		
		userBean.setRoles(list2);
		userBean.setUserObj(user);
		
		//单方登录 设置用户code
		String uskey = RedisConstant.getKey(ResultInfo.USER_CODE_KEY,user.getId());
		if(registrationId!=null&&StringUtils.isNotBlank(registrationId)) {
			if(redisDao.exist(uskey)){
				redisDao.set(uskey,registrationId,userSeconds);
			}else {
				redisDao.add(uskey, userSeconds,registrationId);
			}
			userBean.setRegistrationId(registrationId);
		}
		
		String uuidKey = UUID.randomUUID().toString();
		String key = RedisConstant.getKey(ResultInfo.USERTOKEN,uuidKey);
		SecurityUtils.addUserBean(redisDao, key,userBean,userSeconds);
		
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.LOGIN_SUCCESS,key);
		
	}
	
	/**
	 * 保存到redis
	 * @author lianglie
	 * @date 2018年11月6日 下午3:17:09
	 * @param userDto
	 * @param redisDao
	 * @return
	 */
	/*private String savaRedis(User user, RedisDao redisDao) {
		String userJson = JSON.toJSONString(user);
		String uuidKey = user.getUsernum();
//		String key = RedisConstant.getKey(ResultInfo.USERTOKEN, uuidKey);
		redisDao.set(uuidKey, userJson, userSeconds);
		return uuidKey;
	}*/
	/**
	 * 找回密码
	 *
	 * @author lihongwu
	 * 2018年11月10日 下午5:11:14
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 */
	@Override
	public Map<String, Object> resetPassword(User user,String phone, String code, String password, String repassword) {
		if(StringUtils.isEmpty(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.SYSTEM_ERROR, "phone");
		}
		if(!CheckUtil.checkMobile(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_ERROR);
		}
		if(!user.getPhone().equals(phone)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_NOT_BINDING);
		}
		if (!StringUtils.isNoneBlank(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR, "code");
		}
		if(!StringUtils.isNumeric(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR);
		}
		//校验验证码
		Map<String, Object> checkCode = CheckUtil.checkCode(phone, code, redisDao);
		if(checkCode!=null){
			return checkCode;
		}
		if(!CheckUtil.checkPwd(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PASSWORD_ERROR);
		}
		if(!repassword.equals(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.REPASSWORD_ERROR);
		}
		
		String passwordMd5 = Md5Utils.getPassword(password,phone);
		user.setPassword(passwordMd5);
		user.setUpdateTime(new Date());
		userMapper.updateByPrimaryKeySelective(user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK);
	}
	
	/*@Override
	public Map<String, Object> changePassword(User user, String oldPassword, String newPassword,
			String newPassword2) {
		// 校验参数
		if (!StringUtils.isNotBlank(oldPassword)) {
			return ResponseUtil.ajaxCheckError(UserCopyInfo.OLDPASSWORD_ERROR1, "oldPassword is null");
		}
		if (!StringUtils.isNotBlank(newPassword)) {
			return ResponseUtil.ajaxCheckError(UserCopyInfo.NEWPASSWORD_ERROR1, "oldPassword is null");
		}
		if (!StringUtils.isNotBlank(newPassword2)) {
			return ResponseUtil.ajaxCheckError(UserCopyInfo.NEWPASSWORD_ERROR2, "oldPassword is null");
		}
		if (!newPassword2.equals(newPassword)) {
			return ResponseUtil.ajaxCheckError(UserCopyInfo.NEWPASSWORD_ERROR3,
					"newPassword is not mathed newPassword2");
		}
		if (!Md5Utils.getPassword(oldPassword, user.getPhone()).equals(user.getPassword())) {
			return ResponseUtil.ajaxCheckError(UserCopyInfo.OLDPASSWORD_ERROR2, "oldPassword is error");
		}
		if (!CheckUtil.checkPwd(newPassword)) {
			return ResponseUtil.ajaxCheckError(UserCopyInfo.PASSWORD_ERROR, "newPassword");
		}
		// 修改密码
		user.setPassword(Md5Utils.getPassword(newPassword, user.getPhone()));
		user.setUpdateTime(new Date());
		userMapper.updateByPrimaryKeySelective(user);
		return ResponseUtil.ajaxCheckSuccess(UserCopyInfo.CHANGEPASSWORD_SUCCESS);
		
		user.setSex(sex);
		user.setUpdateTime(new Date());
		
		userMapper.updateByPrimaryKeySelective(user);
		
		//将用户数据保存到redis中并将redis中的key返回
		String key = saveUserByRedis(redisDao, user);
		return ResponseUtil.ajaxCheckSuccess(UserCopyInfo.UPDATE_SUCCESS,ResultInfo.USERTOKEN,key);	
	}*/
	
	/**
	 * 生成二维码
	 * 
	 * @author chenwei
	 * @date 2018年7月2日 下午5:33:48
	 * @param path fastdfs配置文件路径 cotroller层 this.getClass().getResource("/fastdfs_client.conf").getPath();
	 * @param LocalPath 本地路径
	 * @param content 内容
	 * @param widthPix 高度
	 * @param heightPix 宽度
	 * @return
	 * @throws IOException
	 */
	public String getQRCode(
			String path,
			String LocalPath,
			String content, 
			int widthPix, 
			int heightPix) throws IOException {
		try {
			if (!StringUtils.isNotBlank(content)) {
				return null;
			}
			//进行base64编码
			//content = Base64.getEncoder().encodeToString(content.getBytes());
			// 配置参数
			Map<EncodeHintType, Object> hints = new HashMap<>();
			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			// 容错级别
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
			// 图像数据转换，使用了矩阵转换
			BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
					heightPix, hints);
			int[] pixels = new int[widthPix * heightPix];
			// 下面这里按照二维码的算法，逐个生成二维码的图片，
			// 两个for循环是图片横列扫描的结果
			for (int y = 0; y < heightPix; y++) {
				for (int x = 0; x < widthPix; x++) {
					if (bitMatrix.get(x, y)) {
						pixels[y * widthPix + x] = 0xff000000;
					} else {
						pixels[y * widthPix + x] = 0xffffffff;
					}
				}
			}
			String fileName = UUID.randomUUID().toString().replaceAll("-", "");
			File file = new File(LocalPath+fileName+"."+FILE_SUFFIX);
			FileOutputStream fos = new FileOutputStream(file);
			MatrixToImageWriter.writeToStream(bitMatrix,FILE_SUFFIX,fos);
			byte[] fileToByte = FileUtil.fileToByte(LocalPath+fileName+"."+FILE_SUFFIX);
			//文件上传
			String uploadFile = FileUtil.uploadFile(path, fileToByte, "png");
			//删除本地文件
			file.deleteOnExit();
			fos.close();
			return uploadFile;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 找回密码
	 *
	 * @author lihongwu
	 * 2019年1月3日 上午9:42:32
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 */
	@Override
	public Map<String, Object> resetPasswordInApp(String phone, String code, String password, String repassword) {
		if(StringUtils.isEmpty(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.SYSTEM_ERROR, "phone");
		}
		if(!CheckUtil.checkMobile(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_ERROR);
		}
		if (!StringUtils.isNoneBlank(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR, "code");
		}
		if(!StringUtils.isNumeric(code)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.CODE_ERROR);
		}
		User user = userMapper.getUserByPhone(phone);
		if(user==null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_ERROR);
		}
		//校验验证码
		Map<String, Object> checkCode = CheckUtil.checkCode(phone, code, redisDao);
		if(checkCode!=null){
			return checkCode;
		}
		if(!CheckUtil.checkPwd(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PASSWORD_ERROR);
		}
		if(!repassword.equals(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.REPASSWORD_ERROR);
		}
		
		String passwordMd5 = Md5Utils.getPassword(password,phone);
		user.setPassword(passwordMd5);
		user.setUpdateTime(new Date());
		userMapper.updateByPrimaryKeySelective(user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK);
	}

	/**
	 * 修改手机号
	 *
	 * @author lihongwu
	 * 2019年1月3日 上午9:57:55
	 * @param user
	 * @param phone
	 * @param code
	 * @param password
	 * @return
	 */
	/*@Override
	public Map<String, Object> resetPhone(User user, String phone, String code, String password) {
		if(StringUtils.isBlank(password)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR);
		}
		if(StringUtils.isBlank(phone)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_IS_NULL);
		}
		String md5Password = Md5Utils.getPassword(password, user.getPhone());
		if(!md5Password.equals(user.getPassword())) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR);
		}
		//校验验证码
		Map<String, Object> checkCode = CheckUtil.checkCode(phone, code, redisDao);
		if(checkCode!=null){
			return checkCode;
		}
		User getUserByPhone = userMapper.getUserByPhone(phone);
		if(getUserByPhone!=null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_BE_BINDING);
		}
		user.setPhone(phone);
		user.setUpdateTime(new Date());
		
		userMapper.updateByPrimaryKeySelective(user);

		// 更新reids和cookie中的用户数据
		String key = saveUserByRedis(redisDao, user);
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.UPDATE_SUCCESS, ResultInfo.USERTOKEN, key);
	}*/

	/**
	 * 获取用户手机号码
	 * @author wujunyuan
	 * @date 2019年1月2日 下午5:33:44
	 * @param request
	 * @param user
	 * @return
	 */
	@Override
	public Map<String, Object> getUserPhone(HttpServletRequest request, User user) {
		if(user==null||StringUtils.isBlank(user.getPhone())) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_IS_NULL,"phone is null");
		}
		Map<String,Object> result = new HashMap<>();
		result.put("userPhone", user.getPhone());
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK,result);
	}
	
	/**
	 * 注册(小程序端)
	 *
	 * @author lihongwu
	 * 2019年1月4日 上午10:11:19
	 * @param request
	 * @param openId
	 * @param name
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @param province
	 * @param city
	 * @param area
	 * @param shopName
	 * @param path
	 * @return
	 * @throws IOException 
	 */
	@Override
	public Map<String, Object> registInWx(HttpServletRequest request, String openId, String name, String phone,
			String code, String password, String repassword, String province, String city, String area, String shopName,
			String path) throws IOException {
		
		if(StringUtils.isBlank(openId)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.SYSTEM_ERROR,"openId is null");
		}
		if(StringUtils.isBlank(name)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.NAME_IS_NULL);
		}
		if(StringUtils.isBlank(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_IS_NULL);
		}
		if(!CheckUtil.checkChineseStr(name, 8)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.NAME_STRING_ERROR);
		}
		if(StringUtils.isNoneBlank(shopName) && !CheckUtil.checkChineseStr(shopName, 8)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.SHOPNAME_STRING_ERROR);
		}
		if(!CheckUtil.checkMobile(phone)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_ERROR);
		}
		if(userMapper.checkPhoneExist(phone)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_BE_REGIST);
		}
		//校验验证码
		Map<String, Object> checkCode = CheckUtil.checkCode(phone, code, redisDao);
		if(checkCode!=null){
			return checkCode;
		}
		if(!CheckUtil.checkPwd(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.PASSWORD_ERROR);
		}
		if(!repassword.equals(password)){
			return ResponseUtil.ajaxCheckError(ResultMessage.REPASSWORD_ERROR);
		}
		
		// 设置用户编号(雪花)
		Calendar now = Calendar.getInstance();
		String orderNum = SnowflakeIdUtil.nextId(3699L, System.currentTimeMillis()) + "";
		String nowTime = (Integer.parseInt(String.valueOf(now.get(Calendar.YEAR)).substring(2)) + "")
				+ (String.format("%02d", (now.get(Calendar.MONTH) + 1)))
				+ (String.format("%02d", now.get(Calendar.DAY_OF_MONTH)))
				+ (String.format("%02d", now.get(Calendar.HOUR_OF_DAY)))
				+ (String.format("%02d", now.get(Calendar.MINUTE)));
		String startLetter = "USER";
		
		String passwordMd5 = Md5Utils.getPassword(password,phone);
		
		//用openId查询用户
		User openIdUser = new User();
		openIdUser.setOpenId(openId);
		openIdUser = userMapper.selectOne(openIdUser);
		if(openIdUser==null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.SYSTEM_ERROR,"openId is error");
		}
		
		//根据openId查询的用户账号密码为空，将注册信息添加到openId查询到的user里
		if(StringUtils.isBlank(openIdUser.getPhone()) && StringUtils.isBlank(openIdUser.getPassword())) {
			openIdUser.setPhone(phone);
			openIdUser.setNickName(name);
			openIdUser.setPassword(passwordMd5);
			openIdUser.setUsernum(startLetter + nowTime + orderNum);
			openIdUser.setCountry(province);  //国这个字段当省用
			openIdUser.setProvince(city);     //省当城市用
			openIdUser.setCity(area);    //城市当区用
			if(StringUtils.isNoneBlank(shopName)) {
				openIdUser.setShopname(shopName);
			}
			openIdUser.setLevel(0);
			openIdUser.setType(0);
			openIdUser.setUpdateTime(new Date());
			userMapper.updateByPrimaryKeySelective(openIdUser);
			
			//制作二维码
			String localPath = request.getSession().getServletContext().getRealPath("/")+"image/";
			String qrCodePath = this.getQRCode(path, localPath,"userId"+openIdUser.getId(), 300, 300);
			openIdUser.setCodea(qrCodePath);
			openIdUser.setUpdateTime(new Date());
			userMapper.updateByPrimaryKeySelective(openIdUser);
			
			//将用户与普通用户角色关联
			RoleUserKey roleUserKey = new RoleUserKey();
			roleUserKey.setUserid(openIdUser.getId());
			roleUserKey.setRoleid(plainId);
			roleUserKeyMapper.insert(roleUserKey);
			
			//生成相关的钱包
			Wallet wallet = new Wallet();
			wallet.setId(UUID.randomUUID().toString().replace("-", ""));
			wallet.setMoney("0");
			wallet.setOutmoney("0");
			wallet.setHistorymoney("0");
			wallet.setCreateTime(new Date());
			wallet.setUpdateTime(new Date());
			walletMapper.insertSelective(wallet);
			
			// 生成相关的钱包关系
			UserWalletKey walletKey=new UserWalletKey();
			walletKey.setUserid(openIdUser.getId());
			walletKey.setWalletid(wallet.getId());
			walletKeyMapper.insertSelective(walletKey);
		}else { //根据openId查询的用户账号密码不为空,则注册的时候新建的一个user，不含有openId
			User user = new User();
			user.setId(UUID.randomUUID().toString().replace("-", ""));
			user.setPhone(phone);
			user.setNickName(name);
			user.setPassword(passwordMd5);
			user.setUsernum(startLetter + nowTime + orderNum);
			user.setCountry(province);  //国这个字段当省用
			user.setProvince(city);     //省当城市用
			user.setCity(area);    //城市当区用
			if(StringUtils.isNoneBlank(shopName)) {
				user.setShopname(shopName);
			}
			user.setLevel(0);
			user.setType(0);
			user.setCreateTime(new Date());
			user.setUpdateTime(new Date());
			userMapper.insertSelective(user);
			
			//制作二维码
			String localPath = request.getSession().getServletContext().getRealPath("/")+"image/";
			String qrCodePath = this.getQRCode(path, localPath,"userId"+user.getId(), 300, 300);
			user.setCodea(qrCodePath);
			user.setUpdateTime(new Date());
			userMapper.updateByPrimaryKeySelective(user);
			
			//将用户与普通用户角色关联
			RoleUserKey roleUserKey = new RoleUserKey();
			roleUserKey.setUserid(user.getId());
			roleUserKey.setRoleid(plainId);
			roleUserKeyMapper.insert(roleUserKey);
			
			//生成相关的钱包
			Wallet wallet = new Wallet();
			wallet.setId(UUID.randomUUID().toString().replace("-", ""));
			wallet.setMoney("0");
			wallet.setOutmoney("0");
			wallet.setHistorymoney("0");
			wallet.setCreateTime(new Date());
			wallet.setUpdateTime(new Date());
			walletMapper.insertSelective(wallet);
			
			// 生成相关的钱包关系
			UserWalletKey walletKey=new UserWalletKey();
			walletKey.setUserid(user.getId());
			walletKey.setWalletid(wallet.getId());
			walletKeyMapper.insertSelective(walletKey);
		}
		
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.OK);
	}

	/**
	 * 登录(小程序端)
	 *
	 * @author lihongwu
	 * 2019年1月4日 下午3:21:54
	 * @param openId
	 * @param phone
	 * @param password
	 * @return
	 * @throws Exception 
	 */
	@Override
	public Map<String, Object> loginInWx(String openId, String phone, String password) throws Exception {
		if(StringUtils.isBlank(openId)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.SYSTEM_ERROR,"openId is null");
		}
		// 判断手机号密码是否为空
		if(StringUtils.isBlank(phone)||StringUtils.isBlank(password)) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR, "phone or password is null");
		}
		//用openId查询用户
		User openIdUser = new User();
		openIdUser.setOpenId(openId);
		openIdUser = userMapper.selectOne(openIdUser);
		if(openIdUser==null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.RELOGIN,"openIdUser is null");
		}
		//密码MD5加密(盐为手机号;)
		String md5Pws = Md5Utils.MD5AddSalt2(password,phone);
		//判断是否存在
		User user = userMapper.selectByPhoneAndPwd(phone,md5Pws);
		if(user==null) {
			return ResponseUtil.ajaxCheckError(ResultMessage.PHONE_PWS_ERROR, "user is null");
		}
		user = userMapper.selectByPrimaryKey(user.getId());
		
		//根据openId查询的用户账号密码为空
		if(StringUtils.isBlank(openIdUser.getPhone()) && StringUtils.isBlank(openIdUser.getPassword())) {
			
				//将openIdUser的openId存进user里,然后删除openIdUser
				user.setOpenId(openIdUser.getOpenId());
				userMapper.updateByPrimaryKeySelective(user);
				userMapper.deleteByPrimaryKey(openIdUser);
			
		}else { //根据openId查询的用户账号密码不为空,信息是齐全的
				//登录的账号跟微信授权的账号不相同
			    if(!user.getPhone().equals(openIdUser.getPhone())) {
			    	//将openIdUser的openId存进user里,然后将openIdUser的openId设置为空
			    	user.setOpenId(openIdUser.getOpenId());
			    	userMapper.updateByPrimaryKeySelective(user);
			    	openIdUser.setOpenId("");
			    	userMapper.updateByPrimaryKeySelective(openIdUser);
			    }
		}
		
		UserBean userBean = new UserBean();
		List<String> list = permissionMaper.getPermissionsByUserId(user.getId());
		userBean.setPermissions(list);
		List<String> list2 = roleMapper.getRolesByUserId(user.getId());
		
		userBean.setRoles(list2);
		userBean.setUserObj(user);
		
		String uuidKey = UUID.randomUUID().toString();
		String key = RedisConstant.getKey(ResultInfo.USERTOKEN,uuidKey);
		SecurityUtils.addUserBean(redisDao, key,userBean,userSeconds);
		
		return ResponseUtil.ajaxCheckSuccess(ResultMessage.LOGIN_SUCCESS,key);
	}
}
